{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python3",
   "display_name": "DataAnalysis"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import nltk\n",
    "%matplotlib inline"
   ]
  },
  {
   "source": [
    "# Chap4 编写结构化的程序\n",
    "1.  怎样才能写出结构良好，可读性强的程序，从而方便重用？\n",
    "2.  基本的结构块，例如：循环、函数和赋值是如何执行的？\n",
    "3.  Python 编程的陷阱还有哪些，如何避免它们？"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "## 4.1 回到 Python 语言的基础"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "source": [
    "### 4.1.1 赋值"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "foo=  Monty ;\t bar=  Monty\nfoo=  Python ;\t bar=  Monty\n"
     ]
    }
   ],
   "source": [
    "# 字符串赋值\n",
    "foo = 'Monty'\n",
    "bar = foo\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)\n",
    "foo = 'Python'\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "foo=  ['Monty', 'Python'] ;\t bar=  ['Monty', 'Python']\nfoo=  ['Monty', 'Bodkin'] ;\t bar=  ['Monty', 'Bodkin']\n"
     ]
    }
   ],
   "source": [
    "# 列表赋值\n",
    "foo = ['Monty', 'Python']\n",
    "bar = foo  # bar 对 foo 只是引用，所以 foo 的改变也会影响到 bar 的值\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)\n",
    "foo[1] = 'Bodkin'\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "empty=  [] ;\t nested=  [[], [], []]\nempty=  ['Python'] ;\t nested=  [['Python'], ['Python'], ['Python']]\n"
     ]
    }
   ],
   "source": [
    "empty = []\n",
    "nested = [empty, empty, empty]\n",
    "print('empty= ', empty, ';\\t', 'nested= ', nested)\n",
    "nested[1].append('Python')\n",
    "print('empty= ', empty, ';\\t', 'nested= ', nested)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "nested=  [['Python'], ['Python'], ['Python']]\nnested=  [['Python'], ['Monty'], ['Python']]\nnested=  [['Python'], ['Monty', 'Monty Python'], ['Python']]\nnested=  [['Python', 'Little Python'], ['Monty', 'Monty Python'], ['Python', 'Little Python']]\n"
     ]
    }
   ],
   "source": [
    "# 通过对象引用修改对象 与 通过覆盖引用修改对象 的区别\n",
    "nested = [[]] * 3\n",
    "nested[1].append('Python')\n",
    "print('nested= ', nested)\n",
    "nested[1] = ['Monty']\n",
    "print('nested= ', nested)\n",
    "nested[1].append('Monty Python')\n",
    "print('nested= ', nested)\n",
    "nested[0].append('Little Python')\n",
    "print('nested= ', nested)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 复制链表（三种拷贝）\n",
    "import copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "foo=  ['Monty', 'Python', [1, 2]] ;\t bar=  ['Monty', 'Python', [1, 2]]\nfoo=  ['Monty', 'Bodkin', [3, 2]] ;\t bar=  ['Monty', 'Bodkin', [3, 2]]\n"
     ]
    }
   ],
   "source": [
    "# 1:直接复制（用等于号），只复制引用\n",
    "\n",
    "foo = ['Monty', 'Python', [1, 2]]\n",
    "bar = foo\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)\n",
    "foo[1] = 'Bodkin'\n",
    "foo[2][0] = 3\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "foo=  ['Monty', 'Python', [1, 2]] ;\t bar=  ['Monty', 'Python', [1, 2]]\nfoo=  ['Monty', 'Bodkin', [3, 2]] ;\t bar=  ['Monty', 'Python', [3, 2]]\n"
     ]
    }
   ],
   "source": [
    "# 2: shadow copy浅拷贝，只复制浅层结构和深层次的引用\n",
    "foo = ['Monty', 'Python', [1, 2]]\n",
    "bar = copy.copy(foo)\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)\n",
    "foo[1] = 'Bodkin'\n",
    "foo[2][0] = 3\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "foo=  ['Monty', 'Python', [1, 2]] ;\t bar=  ['Monty', 'Python', [1, 2]]\nfoo=  ['Monty', 'Bodkin', [3, 2]] ;\t bar=  ['Monty', 'Python', [1, 2]]\n"
     ]
    }
   ],
   "source": [
    "# 3: deep copy 深拷贝，不复制任何引用，只复制结构\n",
    "foo = ['Monty', 'Python', [1, 2]]\n",
    "bar = copy.deepcopy(foo)  # 复制 foo 的结构，而不复制引用\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)\n",
    "foo[1] = 'Bodkin'\n",
    "foo[2][0] = 3\n",
    "print('foo= ', foo, ';\\t', 'bar= ', bar)"
   ]
  },
  {
   "source": [
    "### 4.1.2 等式"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "[['Python'], ['Python'], ['Python']]\nTrue\nTrue\nFalse\n"
     ]
    }
   ],
   "source": [
    "size = 2\n",
    "python = ['Python']\n",
    "snake_nest = [python] * size\n",
    "snake_nest.insert(0, ['Python'])\n",
    "print(snake_nest)\n",
    "print(snake_nest[0] == snake_nest[1] == snake_nest[2])\n",
    "print(snake_nest[1] is snake_nest[2])\n",
    "print(snake_nest[1] is snake_nest[2] is snake_nest[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "position=  0\n[['Python'], ['Python'], ['Python']]\nTrue\nFalse\n[['Monty Python'], ['Python'], ['Python'], ['Python']]\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "\n",
    "size = 3\n",
    "position = random.choice(range(size))\n",
    "print(\"position= \", position)\n",
    "snake_nest = [python] * size\n",
    "snake_nest[position] = ['Python']\n",
    "print(snake_nest)\n",
    "print(snake_nest[0] == snake_nest[1] == snake_nest[2]) \n",
    "print(snake_nest[0] is snake_nest[1] is snake_nest[2]) \n",
    "snake_nest.insert(0, ['Monty Python'])\n",
    "print(snake_nest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "[192327240, 139306120, 139305800, 139305800]"
      ]
     },
     "metadata": {},
     "execution_count": 12
    }
   ],
   "source": [
    "# id(snake) 字符串签名编码\n",
    "[id(snake) for snake in snake_nest]"
   ]
  },
  {
   "source": [
    "### 4.1.3 条件语句"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "cat\n['dog']\n"
     ]
    }
   ],
   "source": [
    "# 条件判别语句\n",
    "mixed = ['cat', '', ['dog'], []]\n",
    "for element in mixed:\n",
    "    if element:  # 非空字符串或非空链表判为真；空字符串或空链表判为假\n",
    "        print(element)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "# 判决短路，第一个条件满足以后，后面的就不再判别就不再执行\n",
    "animals = ['cat', 'dog']\n",
    "if 'cat' in animals:\n",
    "    print(1)\n",
    "elif 'dog' in animals:\n",
    "    print(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "all()=  False\nany()=  True\n"
     ]
    }
   ],
   "source": [
    "sent = ['No', 'good', 'fish', 'goes', 'anywhere', 'without', 'a', 'porpoise', '.']\n",
    "print(\"all()= \", all(len(w) > 4 for w in sent))  # all()检查全部满足条件\n",
    "print(\"any()= \", any(len(w) > 4 for w in sent))  # any()检查部分满足条件"
   ]
  }
 ]
}